home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 7: Sunsite
/
Linux Cubed Series 7 - Sunsite Vol 1.iso
/
system
/
news
/
readers
/
skim-0.8
/
skim-0
/
skim-0.8.4
/
GetSubjectsOfNewArticlesInGroup.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-02-18
|
8KB
|
284 lines
/*
* NAME
* GetSubjectsOfNewArticlesInGroup.c
* USAGE
* GetSubjectsOfNewArticlesInGroup GroupName
* DESCRIPTION
* Retrieve the header lines (Author, Lines, Subject) from the NNTP server
* for all articles in group `GroupName' starting with article number
* `FromArticleNumber'.
* IMPLEMENTATION NOTES
* The algorithm is:
*
* - Send the XOVER command to the NNTP server.
*
* This step is in main() in this file.
*
* - Receive and convert header lines.
*
* This step is in ConvertOverviewToHeaderLine() in this file.
*
* - Match with AutoSelect and Kill patterns.
*
* This step is in ASAKExecute() in AutoSelectAndKill.c.
*
* - Merge the lines which were not killed with the existing contents
* of the Subjects file.
*
* This step is in ASAKClose() in AutoSelectAndKill.c.
*
* - Sort the lines by subject, ignoring the "Re: " prefix (pseudo
* threading).
*
* This step is in ASAKClose() in AutoSelectAndKill.c.
*
* - Write the result to the Subjects file.
*
* This step is in ASAKClose() in AutoSelectAndKill.c.
* COPYRIGHT
* Skim - Off-line news reading package optimized for slow lines.
* Copyright (C) 1996 Rene W.J. Pijlman
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* VERSION
* Skim version 0.8.4.
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>
#include "MemAlloc.h"
#include "Skim.h"
#include "NNTPStream.h"
#include "SkimUtils.h"
#include "AutoSelectAndKill.h"
#include "ArticleNumber.h"
#include "StandardIO.h"
FILE_ID("$Header: /home/rene/sys/CVS_MasterSourceRepository/skim/GetSubjectsOfNewArticlesInGroup.c,v 1.7 1996/02/17 22:47:31 rene Exp $");
#define HEADER_SUBJECT "Subject"
#define HEADER_FROM "From"
#define HEADER_LINES "Lines"
static int OverviewOffsetArticleNumber = 0;
static int OverviewFmtOffsetSubject = 0;
static int OverviewFmtOffsetFrom = 0;
static int OverviewFmtOffsetLines = 0;
const char InputSeparator = '\t';
const char Overflow = '*';
static void FixSizeOfLinesField( VarBuf Target )
{
if ( VBSize(Target) > LengthOfNumberOfLines() )
{
int i;
VBReset( Target );
for ( i = 0; i < LengthOfNumberOfLines(); i++ )
{
VBAppendCharacter( Target, Overflow );
}
}
else
{
VBShiftRight( Target, LengthOfNumberOfLines() - VBSize( Target ),
PadCharacter );
}
assert( VBSize( Target ) == LengthOfNumberOfLines() );
}
static void MissingFieldError( char * Field )
{
SIOPrintf( StandardError,
"The `%s' field is missing in the overview from the news server.\n",
Field );
exit( EXIT_FAILURE );
}
static void ConvertOverviewToHeaderLine( VarBuf Target )
{
VarBuf Overview = VBCreate();
VBAppendVB( Overview, Target );
VBReset( Target );
VBAppendCharacter( Target, NotSelected );
VBFixSize( Target, OffsetOfArticleNumber() - 1, PadCharacter );
VBAppendCharacter( Target, PadCharacter );
/* Append article number. */
if ( !AppendFieldFromSeparatorRecord( Target, Overview, InputSeparator,
OverviewOffsetArticleNumber, NULL ) )
{
MissingFieldError( "Article number" );
}
VBFixSize( Target, OffsetOfAuthor() - 1, PadCharacter );
VBAppendCharacter( Target, PadCharacter );
/* Append author. */
if ( !AppendFieldFromSeparatorRecord( Target, Overview, InputSeparator,
OverviewFmtOffsetFrom, AuthorFromFromField ) )
{
MissingFieldError( "From" );
}
VBFixSize( Target, OffsetOfLines() - 1, PadCharacter );
VBAppendCharacter( Target, PadCharacter );
/* Append number of lines, if available in the overview database. */
if ( OverviewFmtOffsetLines > 0 )
{
if ( !AppendFieldFromSeparatorRecord( Target, Overview, InputSeparator,
OverviewFmtOffsetLines,
FixSizeOfLinesField ) )
{
MissingFieldError( "Lines" );
}
}
VBFixSize( Target, OffsetOfSubject() - 1, PadCharacter );
VBAppendCharacter( Target, PadCharacter );
/* Append subject. */
if ( !AppendFieldFromSeparatorRecord( Target, Overview, InputSeparator,
OverviewFmtOffsetSubject, NULL ) )
{
MissingFieldError( "Subject" );
}
VBDestroy( Overview );
}
/* Determine the offset of a field in the overview. */
static void InterpretOverviewFmt( VarBuf Line )
{
static int OverviewFmtCounter = 0;
OverviewFmtCounter++;
if ( !strncasecmp( VBAsString( Line ), HEADER_SUBJECT,
strlen(HEADER_SUBJECT) ) )
{
OverviewFmtOffsetSubject = OverviewFmtCounter;
}
else if ( !strncasecmp( VBAsString( Line ), HEADER_FROM,
strlen(HEADER_FROM) ) )
{
OverviewFmtOffsetFrom = OverviewFmtCounter;
}
else if ( !strncasecmp( VBAsString( Line ), HEADER_LINES,
strlen(HEADER_LINES) ) )
{
OverviewFmtOffsetLines = OverviewFmtCounter;
}
}
static const char * NeedXover =
"Skim: the news server returned an error when skim issued the \"list\n\
overview.fmt\" or the \"XOVER\" command. Perhaps your news server doesn't\n\
support these NNTP extensions. Skim needs these commands for access to the\n\
News OverView (NOV) database. This is becoming a defacto standard for\n\
efficiently accessing header information via NNTP. Check with your ISP or\n\
news administrator. When the news server doesn't support the NOV database\n\
skim is of no use to you. Sorry.\n";
int main( int argc, char **argv )
{
VarBuf Command = VBCreate();
StandardIO NewsServer;
if ( argc != 2 )
{
SIOPrintf( StandardError, "%s\n",
"Usage: GetSubjectsOfNewArticlesInGroup GroupName" );
exit( EXIT_FAILURE );
}
if ( strlen(argv[1]) > 0 )
{
/* Open standard I/O stream to NNTP server. */
NewsServer = NNTPStreamOpen();
SIOInternetCommand( NewsServer, "list overview.fmt" );
CheckStatusResponse( NewsServer, argv[1], "215", NeedXover,
TERMINATE_ON_ERROR );
GetTextResponse( NewsServer, InterpretOverviewFmt, NULL, NULL, NULL );
if ( OverviewFmtOffsetSubject == 0 || OverviewFmtOffsetFrom == 0 )
{
SIOPrintf( StandardError,
"The overview database of your news server does not contain the `%s'\n"
"header line.\n", OverviewFmtOffsetSubject == 0 ? "Subject" : "From" );
exit( EXIT_FAILURE );
}
/* Make group current. */
VBReset( Command );
VBPrintf( Command, "group %s", argv[1] );
SIOInternetCommand( NewsServer, VBAsString( Command ) );
CheckStatusResponse( NewsServer, argv[1], "2", NULL, TERMINATE_ON_ERROR );
/*
* Retrieve the subject lines.
*
* Note: the xover command is not part of the NNTP protocol in RFC-977.
* The RFC does allow extensions, however, and I think many servers do
* support the xover command. When in doubt, query your NNTP server:
*
* telnet $NNTPSERVER 119
* help
* ...
* XOVER ...
* quit
*/
VBReset( Command );
VBPrintf( Command, "xover %lu-", GetCurrentArticleNumber(argv[1]) );
SIOInternetCommand( NewsServer, VBAsString( Command ) );
CheckStatusResponse( NewsServer, argv[1], "2",
NeedXover, TERMINATE_ON_ERROR );
ASAKOpen( argv[1] );
GetTextResponse( NewsServer, ConvertOverviewToHeaderLine,
NULL, NULL, ASAKExecute );
NNTPStreamClose( NewsServer );
ASAKClose();
}
VBDestroy( Command );
return EXIT_SUCCESS;
}